package com.ruoyi.framework.config;

import java.util.HashMap;
import java.util.Map;
import javax.servlet.DispatcherType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.filter.RepeatableFilter;
import com.ruoyi.common.filter.XssFilter;
import com.ruoyi.common.utils.StringUtils;

/**
 * Filter配置
 *
 * @author ruoyi
 */
@Configuration
public class FilterConfig
{
    @Value("${xss.excludes}")
    private String excludes;

    @Value("${xss.urlPatterns}")
    private String urlPatterns;

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    @ConditionalOnProperty(value = "xss.enabled", havingValue = "true")//xss.enabled为true的时候开启
    public FilterRegistrationBean xssFilterRegistration()
    {
        //创建 Spring 提供的过滤器注册器，用于配置和注册自定义过滤器。
        FilterRegistrationBean registration = new FilterRegistrationBean();
        //指定过滤器仅对REQUEST类型的请求生效（即普通的 HTTP 请求）。
        registration.setDispatcherTypes(DispatcherType.REQUEST);
        //设置要注册的过滤器实例为XssFilter（Ruoyi 框架中实现 XSS 过滤逻辑的核心类）。
        registration.setFilter(new XssFilter());
        //设置过滤器拦截的 URL 路径，通过StringUtils.split(urlPatterns, ",")从配置中读取并拆分多个路径。
        registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
        registration.setName("xssFilter");
        //设置过滤器的执行顺序为最高优先级（HIGHEST_PRECEDENCE），确保 XSS 过滤在其他过滤器之前执行，提前拦截恶意脚本。
        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
        //向过滤器传递初始化参数，这里主要设置excludes（需要排除过滤的路径），使特定路径不经过 XSS 过滤（例如某些需要提交 HTML 的接口）。
        Map<String, String> initParameters = new HashMap<String, String>();
        initParameters.put("excludes", excludes);
        registration.setInitParameters(initParameters);
        return registration;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean someFilterRegistration()
    {
        //创建过滤器注册器实例，用于配置和注册RepeatableFilter。
        FilterRegistrationBean registration = new FilterRegistrationBean();
        //指定要注册的过滤器为RepeatableFilter，该过滤器的核心作用是包装HttpServletRequest，使得请求体（输入流）可以被多次读取。
        registration.setFilter(new RepeatableFilter());
        //设置过滤器拦截所有 URL 路径（/*表示匹配所有请求），确保所有请求都能被处理。
        registration.addUrlPatterns("/*");
        //为过滤器指定名称 “repeatableFilter”，用于标识该过滤器。
        registration.setName("repeatableFilter");
        //设置过滤器的执行顺序为最低优先级（LOWEST_PRECEDENCE），意味着它会在其他过滤器之后执行。这是因为它的作用是 “支持重复读取”，需要在其他过滤器完成首次读取后再提供重复读取能力，避免干扰其他过滤器的正常处理。
        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
        return registration;
    }

}
